package com.freesky.biz.utils;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

public class AbChinaUtils {

    private static final String KEY_ALGORITHM = "AES";

    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    private static SecretKeySpec getSecretKey(final String key){
        try{
            KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8));
            kg.init(128,secureRandom);
            SecretKey secretKey = kg.generateKey();
            return new SecretKeySpec(secretKey.getEncoded(),KEY_ALGORITHM);
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] aesEncrypt(String data,String aesKey) throws Exception{
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,getSecretKey(aesKey));
        return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
    }

    public static String aesDecrypt(String data,String aesKey) throws Exception{
        byte[] byteData = Base64.decodeBase64(data);
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,getSecretKey(aesKey));
        byte[] result = cipher.doFinal(byteData);
        return new String(result,"utf-8");
    }

    //http://t.zoukankan.com/lene-y-p-11579997.html
    //用私钥签名
    public static String sign(String data,String privateKey) throws Exception{
        byte[] byteData = data.getBytes();
        byte[] keyBytes = Base64.decodeBase64(privateKey);

        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");//这个根据需求填充SHA1WithRSA或SHA256WithRSA
        signature.initSign(priKey);
        signature.update(byteData);
        return Base64.encodeBase64String(signature.sign());
    }

    //用公钥验签
    public static boolean verifySign(String data,
                                   String signData,
                                   String publicKeyStr) throws Exception{
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("Sha256WithRSA");
        signature.initVerify(publicKey);
        signature.update(data.getBytes("UTF-8"));
        boolean verify = signature.verify(Base64.decodeBase64(signData));
        return verify;
    }

    /**
     * 使用私钥对数据进行加密
     */
    public static byte[] encryptPrivateKey(byte[] binaryData, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        // 获取RSA算法实例
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key priKey = keyFactory.generatePrivate(keySpec);

        // 初始化加密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, priKey);
        return cipher.doFinal(binaryData);
    }

    /**
     * 使用私钥对数据进行加密并签名
     */
    public static byte[] encryptPrivateKeyAndSign(byte[] binaryData, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(privateK);
        signature.update(binaryData);
        return signature.sign();
    }

    /**
     * 使用公钥对数据进行加密
     */
    public static byte[] encryptPublicKey(byte[] binaryData, String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
//        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
//        // 获取RSA算法实例
//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//        Key publicK = keyFactory.generatePublic(keySpec);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicK = KeyFactory.getInstance("RSA")
                .generatePublic(new X509EncodedKeySpec(keyBytes));
        // 初始化加密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        return cipher.doFinal(binaryData);
    }

    public static byte[] decryptPublicKey(byte[] binaryData, String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicK = KeyFactory.getInstance("RSA")
                .generatePublic(new X509EncodedKeySpec(keyBytes));
        // 初始化加密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        return cipher.doFinal(binaryData);
    }

    /**
     * 使用私钥对数据进行解密
     */
    public static byte[] decryptPrivateKey(byte[] binaryData, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

        // 获取RSA算法实例
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key priKey = keyFactory.generatePrivate(keySpec);

        // 初始化加密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return cipher.doFinal(binaryData);
    }



    //字段名的ASCII码从小到大排序（字典序）
    public static String sortMap(Map<String, String> params) {
        SortedMap<String, String> sortedParamMap = new TreeMap<String, String>(params);
        StringBuffer buffer = new StringBuffer();
        Iterator<Map.Entry<String, String>> iter = sortedParamMap.entrySet()
                .iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> kvpair = iter.next();
            buffer.append(kvpair.getKey().toLowerCase(Locale.ROOT));
            buffer.append("=");
            buffer.append(kvpair.getValue().toString());
            if (iter.hasNext()) {
                buffer.append("&");
            }
        }
        return buffer.toString();
    }

    //sha256签名
    public static String signBySha256(String data) throws Exception {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        messageDigest.update(data.getBytes("UTF-8"));
        String encodeStr = Convert.toHex(messageDigest.digest());
        return encodeStr;
    }

    public static void main(String args[]) throws Exception, InvalidAlgorithmParameterException {
//        String dataStr = "{\"appid\":\"9999\",\"name\":\"Lisan\",\"reqTime\":\"1620277049\",\"version\":\"3.0.0\"}";
//        String privateKey = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkwQuN4DoJ0X3QQPnbBuEFkmWi1LNlXez1kQAexJ1d7uwpYTTo7jPPsuc+PbrNZ4MHC+62U7Ruyk9rKHXPDOHcwIDAQABAkAAyGvqlcAmvWOkr/2igL8CU1/+2/EGU73cbT5HaYDAo3glBcaW0MOrl7VgrYtFjsu/htSuzwr2KqR6mbAlzHNBAiEA4orXbQ3FDO6XPixosJ2ChTsO/O3wgxLG9Bw/ChJrnhMCIQCmIhItq7LaQf1gt1dAYz6C+aSfYDMyoVbPnu8W5GQdIQIgELzFUc9UobH3BqbtTS8193X3k4RY4rY+cMateacGwHUCIH+aEb5Ub5YmM1gy2ehRkfUFjAUB3bEYrNXhbCB4IdEhAiBbltA/8U7LIIb8auaESX+/Fq7RINKcoioeTpjii9RvPA";
//
//        byte[] encryptBusinessBytes = AbChinaUtils.aesEncrypt(dataStr, "f5gae2sdgjcialidgwgtlgcehzc");
//        String data = Base64.encodeBase64String(encryptBusinessBytes);
//        System.out.println("data:"+data);
//        System.out.println(AbChinaUtils.aesDecrypt(data,"f5gae2sdgjcialidgwgtlgcehzc"));
//        System.out.println(AbChinaUtils.sign(dataStr,privateKey));
//
//        System.out.println( UUID.randomUUID());
//
//        String mobile = "18650992221";
//        System.out.println(mobile.substring(0,7));
        //String RSA_BANK_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8uKfkF5rct8coWq8GZH4Puy+JH1baa6TtwgOtGesE+fj+Bu3mK+ovxaSTLEy+xUUKGFxiXy+n3jwV1/6CjxbVZ+MM7biso+yky/gX19AFyhjGZxZG6+e2TJ7ppaaZV+8rO638OTeSCiR6c/Yn4wMz2Q0rTZbh8zDXINvv0sgVXwIDAQAB";
        String RSA_BANK_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8uKfkF5rct8coWq8GZH4Puy+JH1baa6TtwgOtGesE+fj+Bu3mK+ovxaSTLEy+xUUKGFxiXy+n3jwV1/6CjxbVZ+MM7biso+yky/gX19AFyhjGZxZG6+e2TJ7ppaaZV+8rO638OTeSCiR6c/Yn4wMz2Q0rTZbh8zDXINvv0sgVXwIDAQAB";
        String TOKEN_RSA_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJO1rzMpozvlU0i2pAi0Sbkgt3H+wLEeJMc96S6AEnVdLDPlFvlPw+O8f5pKOcKe1ZRdFtQtiZMnwBsbDB7qBPEi6DJhUgSmtO+VOhOIUi74hCgsacKcWkHY+sqwUwmDXbNaxxgOGk7v98KuTQoRJY06oKvYgdq0CPHJ0tUymEv3AgMBAAECgYBZLXS0L+xESiTpHpOUSbzEz1LRuRt/E5Li06cHkv0R7Im2XxZquNSslu53KV8L+Dc8VqNkwIVx2arq8n5z35fRTxKi1uXxemM/u/TWcT4bqf5VZCvK3rEtr9T4MJ6MVF+WFyNQ4VbrIjGbVWaWFm0h5i++peImeqlXOam2FXZS0QJBAMLTISxUoIpVrolHcaE71w+PwcEUUnD0fWThqGiPpSGgAdKealZio1C6B19KQAAPoLhMLzKmqhE6LwMEolCXhF8CQQDCFz3hD9dXDp4BwPdBQbMhYUGHwwv7/BpN67N/HBIfS1N6jL571qv4fzseIwHHuG+pQzaFg4gUao26jTcgRJ9pAkAfRrennzpamuC3JyIFyU6AMArhzTpi6c0LmfJoPs86s643OrlFfvZK6mJumMPnfprFm21kSz84HsgXSvInz/svAkEAoKboOzAHiDG7K6xzfHpLMSf1O9CATPThOPoNuvqbLXgGAvwYdxy7f5agclN7l7rcAfh2WpECxBNmeLGGnZjvcQJAH4wYITxXC2cn0rIJpsGHMhnXwrFQBi2GIW5fP9ikEAXKt+un+oLQpwUlX9QWxaetDQwoYTFK0wqMU8XGL1QuZg==";

        String dataStr = "{\"sign\":\"d/xBMBARjZk7jrUvLxp3wUbVpjDIat0tVOuVxAjIcpj/cPsEVlDJK9SO5J6rE+tqIKKd3zPyxJQe3P9pUd3fUBOwIbxs3WF6pjxfZeor0gBeS6IAKSRCnCdfCBe+r798ZRjQGvFpYGCTV6iKohbZfXCLUAByMkAdjt23q2Tbm5A=\",\"user_id\":\"ULtNn+DDS33+/iZyxKqlwf1wNWluGwIpnP8OEOOtge1rOJ3bOiKLfKqyo3fozW9t5IjluBIkAozDfnQXigcn/XWZzKAqFgdjQboU21wGQI7CumbL1cBCqNwTDIeheB4EolcIJGfda2uym53DUyuUbp7zSouc9uUckG6VzqI71qs=\"}";
        JSONObject jsonObject = JSON.parseObject(dataStr);
        String actId = jsonObject.getString("act_id");
        String reserveBak = jsonObject.getString("reserve_bak");
        String reqNo = jsonObject.getString("req_no");
        String userId = jsonObject.getString("user_id");
        String mobile = new String(AbChinaUtils.decryptPublicKey(Base64.decodeBase64(userId), RSA_BANK_PUBLIC_KEY));
        System.out.println("mobile:"+mobile);

        //order_no=M1838838748983250944&status=SUCCESS&supplier_no=SN7335960413&timestamp=1727282011&sign=AFA8763544454EE4BF94523A638D92D0
        Map<String, String> reqMap = new HashMap<>();
        reqMap.put("order_no","M1838838748983250944");
        reqMap.put("status","SUCCESS");
        reqMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
        reqMap.put("supplier_no", "SN7335960413");

        String oriSignInfo = AbChinaUtils.sortMap(reqMap) + "&appSecret=E9NSRTGXZALVAGYTYKCL0MPSNV0W0TNV";
        String md5Hex = DigestUtils.md5Hex(oriSignInfo).toUpperCase();
        System.out.println("oriSignInfo:"+oriSignInfo+","+ md5Hex);
        //https://docking.dz.chengjifen.com/szhlh_web/orderNotify?order_no=M1838838748983250944&status=SUCCESS&supplier_no=SN7335960413&timestamp=1727311015103&sign=1F0C7C272699FC1BF346FAB9C36184A2

    }
}
